package com.zimin.cloud.system.biz.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zimin.cloud.mine.pojo.system.business.RoleBO;
import com.zimin.cloud.mine.pojo.system.view.RoleVO;
import com.zimin.cloud.system.biz.IRoleBiz;
import com.zimin.cloud.system.pojo.entity.Role;
import com.zimin.cloud.system.pojo.entity.RoleMenu;
import com.zimin.cloud.system.service.IAccountRoleService;
import com.zimin.cloud.system.service.IRoleMenuService;
import com.zimin.cloud.system.service.impl.RoleServiceImpl;
import com.zimin.common.annotation.Biz;
import com.zimin.common.enums.Status;
import com.zimin.common.exception.GraceException;
import com.zimin.common.utils.BeanUtils;
import com.zimin.common.utils.ObjectUtils;
import com.zimin.shared.enums.ResponseStatusEnum;
import com.zimin.shared.pojo.PageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 角色信息 业务对象
 * </p>
 *
 * @author zimin
 * @since 2021-12-30 11:05
 */
@Biz("roleBiz")
public class RoleBizImpl extends RoleServiceImpl implements IRoleBiz {

    @Autowired
    private IRoleMenuService roleMenuService;
    @Autowired
    private IAccountRoleService accountRoleService;

    @Override
    public PageVO<RoleVO> pageRoleList(Page<Role> rolePage, RoleBO roleBO) {
        var rolePageList = super.page(rolePage, super.queryWrappers(roleBO));
        return pageToPageVO(rolePageList, BeanUtils.listEntityToView(rolePageList.getRecords(), RoleVO.class));
    }

    @Override
    public RoleVO getRoleVoById(String roleId) {
        var menuIdByRoleId = roleMenuService.getMenuIdByRoleId(roleId);
        var role = getById(roleId);
        GraceException.isNull(role, ResponseStatusEnum.ROLE_IS_NOT_EXIST);
        var roleVO = BeanUtils.coverClass(role, RoleVO.class);
        roleVO.setRoleMenuList(menuIdByRoleId);
        return roleVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(RoleBO roleBO) {
        var role = BeanUtils.coverClass(roleBO, Role.class);
        GraceException.isNotNull(super.getRoleByName(roleBO.getRoleName()), ResponseStatusEnum.ROLE_NAME_IS_EXIST);
        GraceException.isNotNull(super.getRoleByKey(roleBO.getRoleKey()), ResponseStatusEnum.ROLE_KEY_IS_EXIST);
        var saveFlag = super.save(role);
        var flag = true;
        if (saveFlag && ObjectUtils.isNotEmpty(roleBO.getRoleMenuList())) {
            var roleId = role.getId();
            roleMenuService.removeByRoleId(roleId);
            var roleMenus = roleBO.getRoleMenuList().parallelStream().map(s -> RoleMenu.builder().roleId(roleId).menuId(s).build()).collect(Collectors.toList());
            flag = roleMenuService.saveBatch(roleMenus);
        }
        return saveFlag && flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(RoleBO roleBO) {
        var updateFlag = super.updateById(BeanUtils.coverClass(roleBO, Role.class));
        var flag = true;
        if (updateFlag && ObjectUtils.isNotEmpty(roleBO.getRoleMenuList())) {
            var roleId = roleBO.getId();
            roleMenuService.removeByRoleId(roleId);
            var roleMenus = roleBO.getRoleMenuList().parallelStream().map(s -> RoleMenu.builder().roleId(roleId).menuId(s).build()).collect(Collectors.toList());
            flag = roleMenuService.saveBatch(roleMenus);
        }
        return updateFlag && flag;
    }


    @Override
    public List<RoleVO> allRole() {
        var roleList = lambdaQuery().eq(Role::getStatus, Status.ABLE.ordinal()).list();
        return BeanUtils.listEntityToView(roleList, RoleVO.class);
    }

    @Override
    public boolean removeByIds(List<String> idList) {
        var removeFlag = super.removeByIds(idList);
        if (removeFlag) {
            accountRoleService.removeByRoleIds(idList);
        }
        return removeFlag;
    }

}
